로딩 중이에요... 🐣
14 의존성이란 | ✅ 저자: 이유정(박사)
의존성이란? (Dependency) 무언가에 의존한다는 뜻으로 함수나 클래스가 직접 만들지 않은 외부의 기능을 사용할 때, 그 외부 기능을 "의존성"이라고 해요.
의존성은 왜 필요한가?
-
중복 제거 여러 함수에서 같은 파라미터나 로직이 필요할 때, 매번 똑같이 작성하면 비효율적이죠.
→ 이걸 한 군데로 모아서Depends()
로 가져오면 훨씬 깔끔해요. -
코드 재사용성 특정 기능(예: 인증, 공통 쿼리 파라미터 등)을 여러 곳에서 재활용할 수 있어요.
-
유지보수 쉬움 의존성을 함수로 분리해두면 나중에 수정이 필요할 때 한 군데만 수정하면 돼요.
-
순서 제어 먼저 실행되어 선처리 가능
-
테스트 편의 가짜 의존성으로 교체 가능 (mocking)
-
문서 자동화 Swagger 문서에 자동 반영
-
보안 처리 인증, 권한 확인을 중앙 집중 관리
-
자원 관리 DB, 파일 등 자원 연결 → 해제 흐름을 의존성으로 구현 가능
일반함수 호출과 비교하여 설명하겠습니다: 일반 함수 호출
def read_items():
user = get_current_user()
return {"user": user}
→ 내가 직접 불러야 해요.
→ get_current_user()
를 안 쓰면 동작 안 해요.
의존성 주입 사용
from fastapi import Depends
@app.get("/items/")
def read_items(user = Depends(get_current_user)):
return {"user": user}
→ FastAPI가 알아서:
get_current_user()
먼저 실행user
에 그 값을 넣어줌- 우리는 그냥
user
만 쓰면 됨
한마디로 요약하면 내가 함수호출을 해서 부르느냐, FastAPI가 대신 부르고 관리해주느냐, 의 차이입니다
디렉토리 구조
myproject/
├── main.py
├── dependencies/
│ └── common.py
dependencies/common.py
from fastapi import Depends
from typing import Annotated
# 공통 쿼리 파라미터
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
# 의존성 타입으로 정의
CommonsDep = Annotated[dict, Depends(common_parameters)]
Annotated
란?
Annotated
는 타입 힌트에 부가적인 의미를 덧붙일 때 사용하는 문법입니다.
Annotated[기본타입, 부가정보]
FastAPI에서는 이걸 통해 다음 두 가지 정보를 같이 전달합니다:
- 데이터의 타입 (
dict
) - 어떻게 주입할 것인지 (
Depends(...)
)
Annotated[dict,
딕셔너리 형태로 사용한 이유는 리턴 형태가 딕셔너리 데이터 이기 때문입니다.
main2.py
from fastapi import FastAPI
from dependencies.common import CommonsDep # 의존성타입 변수
app = FastAPI()
@app.get("/items/")
async def read_items(commons: CommonsDep):
return commons
@app.get("/users/")
async def read_users(commons: CommonsDep):
return commons
사용자가 /items/?q=apple&skip=2
같은 요청을 보내면
FastAPI가 자동으로 common_parameters()
를 실행하고
결과 딕셔너리인 {"q": "apple", "skip": 2, "limit": 100}
을 commons
변수에 넣어줘요.
실행예시:
GET /items?q=hello&skip=1&limit=5
응답:
{
"q": "hello",
"skip": 1,
"limit": 5
}
참고 예시코드: 특정 라우터에서만 사용(한 파일에 의존성 코드 표현)
from fastapi import FastAPI, Depends
app = FastAPI()
# 의존성 함수 정의
async def get_token_header(x_token: str = "default"):
return x_token
# 필요한 라우터에서만 사용
@app.get("/items/")
async def read_items(token: str = Depends(get_token_header)):
return {"token": token}
# 여긴 안 써도 됨!
@app.get("/ping")
async def ping():
return {"message": "pong"}
여러 개 주입도 가능
async def get_user(): ...
async def get_settings(): ...
@app.get("/dashboard/")
async def dashboard(
user = Depends(get_user),
settings = Depends(get_settings)
):
return {"user": user, "settings": settings}